#pragma once

#ifndef EDITOR__SETTINGS__WIDGET__HH__
#define EDITOR__SETTINGS__WIDGET__HH__

#include <string>
#include <qstring.h>
#include <OgreString.h>
#include <OgreStringVector.h>
#include <OgreColourValue.h>

#include <qboxlayout.h>
#include <qcolordialog.h>
#include <qlabel.h>
#include <qslider.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qcheckbox.h>
#include <qspinbox.h>
#include "LitEditorSettingsMap.h"

namespace Lit
{
	namespace Editor
	{
		class LIT_API SettingsItemWidget : public QWidget
		{
			Q_OBJECT

		protected:
			std::string mName;
		public:
			SettingsItemWidget(QWidget * parent = NULL) : QWidget( parent ){}
			virtual ~SettingsItemWidget(){}
			
			void setName( const std::string &name ){ mName = name; }
			const std::string& getName() const{ return mName; }

			virtual std::string getValue() = 0;

		signals:
			void itemChanged( const QString &name, const QString &val );
		};

		class LIT_API SettingsTextWidget : public SettingsItemWidget
		{
			Q_OBJECT
			
			QLineEdit * mEdit;
		public:
			template<typename T>
			SettingsTextWidget(const T &value, QWidget*parent) 
				: SettingsItemWidget( parent )
			{
				QHBoxLayout * lay = new QHBoxLayout(this);
				mEdit = new QLineEdit( this );
				mEdit->setText( TO_QT(Lit::String(value).str()) );
				lay->addWidget( mEdit );
				setLayout( lay );
				
				lay->setContentsMargins( 1,1,1,1 );
				mEdit->setContentsMargins( 1, 1, 1, 1 );
				connect( mEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged( const QString & )) );
			}
			~SettingsTextWidget();

			virtual std::string getValue();

		protected slots:
			void textChanged( const QString &val );
		};
		
		class LIT_API SettingsDoubleWidget : public SettingsItemWidget
		{
			Q_OBJECT
			
			QDoubleSpinBox * mSpin;
		public:
			SettingsDoubleWidget( double min, double max, double value, QWidget*parent) ;
			~SettingsDoubleWidget();

			virtual std::string getValue();

		protected slots:
			void valueChanged( double val );
		};
		class LIT_API SettingsIntWidget : public SettingsItemWidget
		{
			Q_OBJECT
			
			QSlider * mSpin;
		public:
			SettingsIntWidget( int min, int max, int value, QWidget*parent) ;
			~SettingsIntWidget();

			virtual std::string getValue();

		protected slots:
			void valueChanged( int val );
		};
		struct LIT_API TextListItems
		{
			size_t mSel;
			std::vector<std::pair<std::string,size_t>> mList;
		public:
			TextListItems(size_t sel=0):mSel(sel){}
			TextListItems(const TextListItems& rk):mSel(rk.mSel), mList(rk.mList){}
			~TextListItems(){}

			void setSelectedValue( size_t val ){ size_t id= 0; for( auto i=mList.begin(); i!=mList.end(); i++ ){ if( (*i).second == val ){ mSel = id; return; } id++; } }
			void setSelected( size_t id ){ mSel = id; }
			TextListItems& add( const std::string &name, size_t val, bool selected = false )
			{
				size_t id = mList.size();
				mList.push_back( std::make_pair( name, val ) );
				if( selected ) mSel = id;
				return *this;
			}
			bool empty() const{ return mList.empty(); }
			size_t getSelectedValue() const{ assert( (!mList.empty()) && mSel < mList.size() ); return mList[mSel].second; }
		};
		class LIT_API SettingsBoolWidget : public SettingsItemWidget
		{
			Q_OBJECT
			
			QCheckBox * mBox;

		public:
			SettingsBoolWidget(bool val, QWidget*parent) ;
			~SettingsBoolWidget();

			virtual std::string getValue();

		protected slots:
			void boolChanged( bool );
		};
		class LIT_API SettingsColorWidget : public SettingsItemWidget
		{
			Q_OBJECT
			
			QLabel * mLabel;
			Lit::Color mColor;
		public:
			SettingsColorWidget(const Lit::Color &value, QWidget*parent) ;
			~SettingsColorWidget();

			void mousePressEvent( QMouseEvent * evt );
			void setColor( const Lit::Color &value );
			virtual std::string getValue();
		};
	};
};

#endif